package com.mijie.homi.api;

import java.io.File;
import java.io.IOException;
import java.io.StringReader;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.apache.log4j.Logger;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.wltea.analyzer.lucene.IKAnalyzer;

import com.mijie.core.ApplicationProperties;
import com.mijie.core.RegionInfo;
import com.mijie.core.Status;
import com.mijie.homi.common.constant.HomiConstants;
import com.mijie.homi.common.constant.HomiStatusCode;
import com.mijie.homi.common.constant.TypeCode;
import com.mijie.homi.common.domain.Grade;
import com.mijie.homi.common.domain.Notify;
import com.mijie.homi.common.domain.SystemMessage;
import com.mijie.homi.common.domain.mood.Mood;
import com.mijie.homi.common.domain.user.DeviceInfo;
import com.mijie.homi.common.domain.user.Friend;
import com.mijie.homi.common.domain.user.Setting;
import com.mijie.homi.common.domain.user.ThirdPartAccount;
import com.mijie.homi.common.domain.user.User;
import com.mijie.homi.common.domain.user.UserExtInfo;
import com.mijie.homi.common.util.HomiUtil;
import com.mijie.homi.domain.user.MoodUser;
import com.mijie.homi.service.chat.ChatService;
import com.mijie.homi.service.common.MixService;
import com.mijie.homi.service.common.StatService;
import com.mijie.homi.service.message.SystemMessageService;
import com.mijie.homi.service.mood.MoodService;
import com.mijie.homi.service.notify.NotifyService;
import com.mijie.homi.service.notify.NotifyUserAgent;
import com.mijie.homi.service.user.DeviceInfoService;
import com.mijie.homi.service.user.FriendService;
import com.mijie.homi.service.user.MoodUserService;
import com.mijie.homi.service.user.PrivacyService;
import com.mijie.homi.service.user.SettingService;
import com.mijie.homi.service.user.ThirdPartAccountService;
import com.mijie.homi.service.user.UserExtInfoService;
import com.mijie.homi.service.user.UserService;
import com.mijie.homi.util.ServerHelper;
import com.mijie.util.FileUploadUtil;
import com.mijie.util.GeoUtil;
import com.mijie.util.Helper;
import com.mijie.util.HttpUtil;
import com.mijie.util.IOUtil;
import com.mijie.util.ImageUtil;

@Controller
@RequestMapping("/user")
public class UserApi {

	private static Logger logger = Logger.getLogger(UserApi.class);
	
	@Autowired
	private UserService userService;
	@Autowired
	private UserExtInfoService userExtInfoService;
	@Autowired
	private SettingService settingService;
	@Autowired
	private NotifyUserAgent notifyUserAgent;
	@Autowired
	private NotifyService notifyService;
	@Autowired
	private MoodUserService moodUserService;
	@Autowired
	private MoodService moodService;
	@Autowired
	private ChatService chatService;
	@Autowired
	private PrivacyService privacyService;
	@Autowired
	private MixService mixService;
	@Autowired
	private ThirdPartAccountService thirdPartAccountService;
	@Autowired
	private FriendService friendService;
	@Autowired
	private DeviceInfoService deviceInfoService;
	@Autowired
	private SystemMessageService systemMessageService;
	
	private  Analyzer ikAnalyzer = new IKAnalyzer(true);
	
	
	@RequestMapping(value="/bind",method=RequestMethod.POST)
	public @ResponseBody void bind(HttpServletRequest request,HttpServletResponse response) throws Exception {
		String content = IOUtil.getContent4InputStream(request.getInputStream());
		JSONObject json = JSONObject.fromObject(content);
		ThirdPartAccount account = new ThirdPartAccount();
		account.setUserId(ServerHelper.getUserId(request));
		account.setType(json.getInt("type"));
		account.setAccessToken(json.getString("accessToken"));
		account.setAccountId(json.getString("accountId"));
		account.setAccountName(json.getString("accountName"));
		int rows = thirdPartAccountService.addThirdPartAccount(account);
		Status status = new Status(request,response);
		if(rows==0) status.setCode(HomiStatusCode.API_EXCEPTION);
		status.write();
	}
	
	
	@RequestMapping(value="/register",method=RequestMethod.POST)
	public @ResponseBody void register(HttpServletRequest request,HttpServletResponse response) throws Exception {
		String content = IOUtil.getContent4InputStream(request.getInputStream());
		JSONObject json = JSONObject.fromObject(content);
		Status status = new Status(request,response);
		if(!Helper.isEmail(json.getString("email"))){
			status.setCode(HomiStatusCode.EMAIL_FORMAT_ERROR);
			status.write();
			logger.info("register fial email:"+json.getString("email"));
			return;
		}
		
		String nickName = json.getString("nickName");
		if(Helper.isInt(nickName) || nickName.length()>HomiConstants.MAX_LENGTH_NICKNAME){
			status.setCode(HomiStatusCode.NICKNAME_FORMAT_ERROR);
			status.write();
			logger.info("register fial nickName:"+json.getString("nickName"));
			return;
		}
		
		
		User user = userService.getUserByEmail(json.getString("email"));
		if(user!=null){
			status.setCode(HomiStatusCode.EMAIL_OCCUPIED);
			status.write();
			logger.info("register fial EMAIL_OCCUPIED");
			return;
		}
		
		
		UserExtInfo extInfo = new UserExtInfo();
		extInfo.setGender(json.getInt("gender"));
		extInfo.setLatitude(json.getDouble("latitude"));
		extInfo.setLongitude(json.getDouble("longitude"));
		extInfo.setTerminalId(json.getString("terminalId"));
		extInfo.setOs(json.getString("os").toLowerCase());
		
		
		DeviceInfo deviceInfo = new DeviceInfo();
		deviceInfo.setCracked(json.getInt("cracked"));
		deviceInfo.setDeviceId(json.getString("deviceId"));
		deviceInfo.setDeviceName(json.getString("deviceName"));
		deviceInfo.setOperators(json.getString("operators"));
		deviceInfo.setOs(json.getString("os").toLowerCase());
		deviceInfo.setOsVer(json.getString("osVer"));
		deviceInfo.setPhoneModel(json.getString("phoneModel"));
		deviceInfo.setScreenSize(json.getString("screenSize"));
		deviceInfo.setMac(json.getString("mac"));
		deviceInfo.setAppVer(json.getString("appVer"));
		
		user = new User();
		user.setNickName(nickName);
		user.setPasswd(json.getString("passwd"));
		user.setGender(json.getInt("gender"));
		user.setEmail(json.getString("email"));
		user.setProvince("");
		user.setCity("");
		
		RegionInfo region = null; 
		if(extInfo.getLongitude()*extInfo.getLatitude()>0){
			region = ApplicationProperties.findRegionInfo(extInfo.getLatitude(), extInfo.getLongitude());
		}
		
		if(region!=null){
			user.setProvince(region.getProvince());
			user.setCity(region.getCity());
		}
		
		int id = userService.register(ServerHelper.getChannel(request),null,user,extInfo,deviceInfo);
		if(id!=0){
			status.setResult("{\"id\":"+id+"}");
		}else{
			logger.info("register fial nickName:"+user.getNickName()+",passwd:"+user.getPasswd()+",email:"+user.getEmail());
			status.setCode(HomiStatusCode.API_EXCEPTION);
		}
		status.write();
	}
	
	@RequestMapping(value="/update",method=RequestMethod.POST)
	public @ResponseBody void update(HttpServletRequest request,HttpServletResponse response) throws IOException{
		String content = null;
		content = IOUtil.getContent4InputStream(request.getInputStream());
		Integer userId = ServerHelper.getUserId(request);
		JSONObject json = JSONObject.fromObject(content);
		Status status = new Status(request,response);
		User user = userService.getUserById(userId);
		if(user==null){
			status.setCode(HomiStatusCode.USER_NOT_FOUND);
			status.write();
			return;
		}
		
		Date now = new Date();
		
		User tmpUser = (User) JSONObject.toBean(json, User.class);
		if(tmpUser.getNickName()!=null){
			tmpUser.setNickName(tmpUser.getNickName().trim());
			if(Helper.isInt(tmpUser.getNickName()) || tmpUser.getNickName().length()>HomiConstants.MAX_LENGTH_NICKNAME){
				status.setCode(HomiStatusCode.NICKNAME_FORMAT_ERROR);
				status.write();
				logger.info("register fial nickName:"+json.getString("nickName"));
				return;
			}
		}
		
		if(tmpUser.getSignature()!=null && tmpUser.getSignature().length()>HomiConstants.MAX_WORD_SIGNATURE){
			status.setCode(HomiStatusCode.CONTENT_LENGTH_LIMIT);
			status.write();
			return;
		}
		
	
		if(tmpUser.getBirthday()!=null && !tmpUser.getBirthday().trim().isEmpty()){
			user.setBirthday(tmpUser.getBirthday());
		}
		if(tmpUser.getPhone()!=null) user.setPhone(tmpUser.getPhone());
		if(tmpUser.getSignature()!=null && !tmpUser.getSignature().trim().isEmpty()) user.setSignature(tmpUser.getSignature());
		if(tmpUser.getPasswd()!=null && !tmpUser.getPasswd().trim().isEmpty()) user.setPasswd(Helper.base64decode(tmpUser.getPasswd()));
		
		if(tmpUser.getNickName()!=null && !tmpUser.getNickName().equals(user.getNickName())){
			userService.updateNickName(userId, tmpUser.getNickName());
		}
		
		if(tmpUser.getName()!=null && !tmpUser.getName().trim().isEmpty() && !tmpUser.getName().equals(user.getName())) 
			userService.updateName(userId, tmpUser.getName());
		
		boolean updateRegion = false;
		if(tmpUser.getNation()!=null && !tmpUser.getNation().equals(user.getNation())) 
			updateRegion = true;
		if(tmpUser.getProvince()!=null && !tmpUser.getProvince().equals(user.getProvince())) 
			updateRegion = true;
		if(tmpUser.getCity()!=null && !tmpUser.getCity().equals(user.getCity())) 
			updateRegion = true;
		if(tmpUser.getDistrict()!=null && !tmpUser.getDistrict().equals(user.getDistrict())) 
			updateRegion = true;
		
		if(updateRegion){
			if(tmpUser.getProvince().startsWith("新 疆")) tmpUser.setProvince("新疆维吾尔自治区");
			userService.updateRegion(userId,tmpUser.getNation(),tmpUser.getProvince(),tmpUser.getCity(),tmpUser.getDistrict());
		}
		
		
		int rows = userService.update(user);
		if(rows==0) status.setCode(HomiStatusCode.API_EXCEPTION);
		status.write();
	}
	
	@RequestMapping(value="/subscribe/add",method=RequestMethod.GET)
	public @ResponseBody void addSubscribe(int targetId,HttpServletRequest request,HttpServletResponse response){
		Status status = new Status(request,response);
		UserExtInfo userExtInfo = userExtInfoService.getUserExtInfoByUserId(targetId);
		if(userExtInfo!=null){
			userService.addUserInfoSubcribe(ServerHelper.getUserId(request), targetId);
			JSONObject result = userService.makeSubscribeMessage(targetId);
			status.setResult(result);
		}else{
			status.setCode(HomiStatusCode.USER_NOT_FOUND);
		}
		status.write();
	}
	
	@RequestMapping(value="/subscribe/delete",method=RequestMethod.GET)
	public @ResponseBody void deleteSubscribe(int targetId,HttpServletRequest request,HttpServletResponse response){
		Status status = new Status(request,response);
		userService.deleteUserInfoSubcribe(ServerHelper.getUserId(request),targetId);
		status.write();
	}
	
	@RequestMapping(value="/info",method=RequestMethod.GET)
	public @ResponseBody void getUserInfo(String account,String password,HttpServletRequest request,HttpServletResponse response){
		Status status = new Status(request,response);
		password = Helper.base64decode(password);
		User user = null;
		if(Helper.isInt(account)){
			user = userService.getUserById(Integer.parseInt(account));
		}else{
			user =  userService.getUserByEmail(account);
		}
		
		status.setCode(HomiStatusCode.USER_NOT_FOUND);
		if(user!=null){
			if(user.getPasswd().equals(password)){
				JSONObject json = JSONObject.fromObject(user);
				json.remove("passwd");
				json.put("createAT", user.getCreateAt());
				status.setResult(json);
				status.setCode(HomiStatusCode.PROC_SUCCESS);
			}
		}
		status.write();
	}
	
	@RequestMapping(value="/get",method=RequestMethod.GET)
	public @ResponseBody void get(int id,HttpServletRequest request,HttpServletResponse response) throws IOException{
		User user = userService.getUserById(id);
		Status status = new Status(request,response);
		Integer userId = ServerHelper.getUserId(request);
		if(user!=null){
			UserExtInfo info = userExtInfoService.getUserExtInfoByUserId(id);
			JSONObject result = JSONObject.fromObject(user);
			result.put("passwd", "null");
			result.put("avatar", HomiUtil.getRealUrl(user.getAvatar()));
			result.put("createAt", user.getCreateAt().getTime());
			result.accumulate("mood", info.getMood());
			result.accumulate("integral", info.getIntegral());
			result.accumulate("albumCover", info.getAlbumCover().startsWith("recommend_")?info.getAlbumCover():HomiUtil.getRealUrl(info.getAlbumCover()));
			result.accumulate("numOfMood", info.getNumOfMood());
			result.accumulate("numOfPhoto", info.getNumOfPhoto());
			result.accumulate("numOfRelatedTopic", info.getNumOfRelatedTopic());
			Grade refGrade = mixService.getRefGradeByIntegral(info.getIntegral());
			result.accumulate("grade", refGrade==null?0:refGrade.getId());
			List<ThirdPartAccount> accountList = thirdPartAccountService.listThirdPartAccountByUser(user.getId());
			JSONArray accountJsonArray = new  JSONArray();
			if(accountList!=null && !accountList.isEmpty()){
				JSONObject accountJson = null;
				ThirdPartAccount ac = null;
				Iterator<ThirdPartAccount> iter = accountList.iterator();
				while(iter.hasNext()){
					ac = iter.next();
					accountJson = new JSONObject();
					accountJson.accumulate("accountId", ac.getAccountId());
					accountJson.accumulate("accessToken", ac.getAccessToken());
					accountJson.accumulate("type", ac.getType());
					accountJsonArray.add(accountJson.toString());
					iter.remove();
				}
				iter = null;
				accountList = null;
			}
			result.accumulate("thirdPartAccounts", accountJsonArray.toString());
			status.setResult(result);
		}else{
			status.setCode(HomiStatusCode.USER_NOT_FOUND);
		}
		status.write();
	}
	
	@RequestMapping(value="/notify/list",method=RequestMethod.GET)
	public @ResponseBody void listNotify(HttpServletRequest request,HttpServletResponse response) throws IOException{
		Status status = new Status(request,response);
		Integer userId = ServerHelper.getUserId(request);
		List<Notify> list = notifyService.listNotifyByUserId(userId);
		
		
		JSONArray result = new JSONArray();
		JSONObject json = null;
		if(!list.isEmpty()){
			Notify notify = null;
			Iterator<Notify> iter = list.iterator();
			while(iter.hasNext()){
				notify = iter.next();
				json = JSONObject.fromObject(notify);
				json.remove("userId");
				//id不可删除,兼容老版本接口
				json.put("notifyId", notify.getId());
				json.put("createAt", notify.getCreateAt().getTime());
				result.add(json);
				iter.remove();
			}
			iter = null;
			list = null;
		}
		
		UserExtInfo userExtInfo = userExtInfoService.getUserExtInfoByUserId(userId);
		int systemMsgMark = userExtInfo.getSystemMsgMark();
		List<SystemMessage> sysMsgList = systemMessageService.getSystemMsg4User(systemMsgMark);
		
		if(sysMsgList != null && !sysMsgList.isEmpty()){
			for(SystemMessage msg : sysMsgList){
				JSONObject msgJson = new JSONObject();
				JSONObject contentJson = JSONObject.fromObject(msg);
				contentJson.put("createAt", msg.getCreateAt().getTime());
				
				msgJson.put("id", "sys_msg_" + msg.getId()); 
				msgJson.put("content", contentJson.toString());
				msgJson.put("notifyId", "sys_msg_" + msg.getId());
				msgJson.put("createAt", msg.getCreateAt().getTime());
				msgJson.put("type", TypeCode.SYSTEM_MESSAGE);
				result.add(msgJson);
				
			}
		}
		
		status.setResult(result);
		status.write();
	}
	
	@RequestMapping(value="/notify/delete",method=RequestMethod.GET)
	public @ResponseBody void deleteNotify(String[] id,HttpServletRequest request,HttpServletResponse response) throws IOException{
		Status status = new Status(request,response);
		Integer userId = ServerHelper.getUserId(request);
		if(id!=null && id.length>0){
			String temp = "";
			for(String str : id){
				temp += str + ",";
			}
			int rows = notifyService.deleteNotify(userId, id);
			if(rows==0){
				status.setCode(HomiStatusCode.API_EXCEPTION);
			}
		}
		status.write();
	}
	
	@RequestMapping(value="/location/update",method=RequestMethod.POST)
	public @ResponseBody void updateLocation(HttpServletRequest request,HttpServletResponse response) throws IOException{
		Integer userId = ServerHelper.getUserId(request);
		double latitude = 0;
		double longitude = 0;
		String ip = HttpUtil.getIp(request);
		if(ip==null) ip = "";
		
		if(ServerHelper.isInternalUser(userId)){
			User user = userService.getUserById(userId);
			double[] lnglat = GeoUtil.getLocationByAddress(user.getProvince()+user.getCity()+user.getDistrict());
			if(lnglat!=null){
				longitude = lnglat[0];
				latitude = lnglat[1];
			}
		}else{
			String content = IOUtil.getContent4InputStream(request.getInputStream());
			JSONObject json = JSONObject.fromObject(content);
			latitude = json.getDouble("latitude");
			longitude = json.getDouble("longitude");
		}
		
		int value = userExtInfoService.updateLocation(userId, latitude, longitude,ip);
		Status status = new Status(request,response);
		if(value==0) status.setCode(HomiStatusCode.API_EXCEPTION);
		status.write();
	}
	
	@RequestMapping(value="/setting/get",method=RequestMethod.GET)
	public @ResponseBody void getSetting(HttpServletRequest request,HttpServletResponse response) throws IOException{
		Integer userId = ServerHelper.getUserId(request);
		Setting setting = settingService.getSettingByUserId(userId);
		Status status = new Status(request,response);
		if(setting==null){
			status.setCode(HomiStatusCode.USER_NOT_FOUND);
		}else{
			JSONObject result = JSONObject.fromObject(setting);
			result.remove("userId");
			status.setResult(result);
		}
		status.write();
	}
	
	@RequestMapping(value="/setting/update",method=RequestMethod.POST)
	public @ResponseBody void updateSetting(HttpServletRequest request,HttpServletResponse response) throws IOException{
		String content = IOUtil.getContent4InputStream(request.getInputStream());
		JSONObject json = JSONObject.fromObject(content);
		Integer userId = ServerHelper.getUserId(request);
		Setting setting = (Setting) JSONObject.toBean(json, Setting.class);
		setting.setUserId(userId);
		int rows = settingService.updateSetting(setting);
		Status status = new Status(request,response);
		if(rows==0) status.setCode(HomiStatusCode.API_EXCEPTION);
		status.write();
	}
	
	@RequestMapping(value="/avatar/upload",method=RequestMethod.POST)
	public @ResponseBody void uploadAvatar(MultipartHttpServletRequest request,HttpServletResponse response) throws IOException{
		Status status = new Status(request,response);
		Integer userId = ServerHelper.getUserId(request);
		
		MultipartFile file  = request.getFile("image");
		if(file==null){
			status.setCode(HomiStatusCode.UPLOAD_FILE_ABSENT);
			status.write();
			return;
		}
		
		if(!FileUploadUtil.validate(file, HomiConstants.IMAGE_SUFFIX)){
			status.setCode(HomiStatusCode.UPLOAD_FILE_ILLEGAL);
			status.write();
			return;
		}
		if(file.getSize()>HomiConstants.IMAGE_MAX_SIZE){
			status.setCode(HomiStatusCode.UPLOAD_FILE_SIZE_LIMIT);
			status.write();
			return;
		}
		
		String avatarLargeHome = ApplicationProperties.get("avatar.large.home");
		String avatarSmalleHome = ApplicationProperties.get("avatar.small.home");
		String basePath = ApplicationProperties.get("resource.path");
		String imageName = FileUploadUtil.upload(file, basePath+avatarLargeHome);
		
		if(imageName!=null){
			File src = new File(basePath+avatarLargeHome+imageName);
			if(src.exists()){
				File dest = new File(basePath+avatarSmalleHome+imageName);
				ImageUtil.zoomWithFixWidth(src, dest, 150, 0.8f);
			}
			int rows = userService.settingAvatar(userId, avatarSmalleHome+imageName);
			if(rows==0) status.setCode(HomiStatusCode.API_EXCEPTION);
			else status.setResult("{\"path\":\""+HomiUtil.getRealUrl(avatarSmalleHome+imageName)+"\"}");
		}else{
			status.setCode(HomiStatusCode.UPLOAD_FILE_FAIL);
		}
		
		status.write();
	}
	
	/**
	 * 为了旧版本不出错暂不删除
	 */
	@RequestMapping(value="/check_nickname",method=RequestMethod.GET)
	public @ResponseBody void checkNickName(String nickName,HttpServletRequest request,HttpServletResponse response) 
			throws IOException{
		Status status = new Status(request,response);
		JSONObject result = new JSONObject();
		result.accumulate("available", true);
		status.setResult(result);
		status.write();
	}
	
	
	@RequestMapping(value="/search",method=RequestMethod.GET)
	public @ResponseBody void search(String idxf,String keyword,int offset,int limit,
			HttpServletRequest request,HttpServletResponse response) throws Exception{
		Status status = new Status(request,response);
		JSONArray result = new JSONArray();
		if(Helper.isInt(keyword)){
			User user = userService.getUserById(Integer.parseInt(keyword));
			if(user!=null){
				UserExtInfo extInfo = userExtInfoService.getUserExtInfoByUserId(user.getId());
				JSONObject json = new JSONObject();
				json.accumulate("id", user.getId());
				json.accumulate("nickName", user.getNickName());
				json.accumulate("gender", user.getGender());
				json.accumulate("avatar", HomiUtil.getRealUrl(user.getAvatar()));
				json.accumulate("province", user.getProvince());
				json.accumulate("city", user.getCity());
				json.accumulate("moodUpdateAt", extInfo.getMoodUpdateAt().getTime());
				json.accumulate("mood", extInfo.getMood());
				result.add(json);
			}
		}else{
			JSONArray ids = userService.searchUser(idxf, keyword, offset, limit);
			if(ids!=null && !ids.isEmpty()){
				JSONObject json = null;
				User user = null;
				Integer id = null;
				UserExtInfo extInfo = null;
				for(int i=0;i<ids.size();i++){
					user = userService.getUserById(ids.getInt(i));
					if(user==null) continue;
					extInfo = userExtInfoService.getUserExtInfoByUserId(user.getId());
					json = new JSONObject();
					json.accumulate("id", user.getId());
					json.accumulate("nickName", user.getNickName());
					json.accumulate("gender", user.getGender());
					json.accumulate("avatar", HomiUtil.getRealUrl(user.getAvatar()));
					json.accumulate("province", user.getProvince());
					json.accumulate("city", user.getCity());
					json.accumulate("moodUpdateAt", extInfo.getMoodUpdateAt()==null?0:extInfo.getMoodUpdateAt().getTime());
					json.accumulate("mood", extInfo.getMood());
					result.add(json);
				}
				ids = null;
			}
		}
		status.setResult(result);
		status.write();
	}
	
	@RequestMapping(value="/list/match",method=RequestMethod.GET)
	public @ResponseBody void listMatch(String idxf,Integer gender,int offset,int limit,
			HttpServletRequest request,HttpServletResponse response) throws Exception{
		Status status = new Status(request,response);
		if(offset==0 || idxf==null) idxf = "";
		if(gender!=null && gender>2) gender = 0;
		if(gender!=null && gender<=0) gender = 0;
		if(gender==null) gender = 0;
		
		JSONArray result = userService.matchUser(idxf, offset, limit, ServerHelper.getUserId(request),gender);
		status.setResult(result);
		status.write();
	}
	
	public  void getKeywords(String str,Set<String> dest) {
		StringReader reader = new StringReader(str); 
	    Integer freq = null;
	    String token = null;
	    String[] natures = null;
	    TokenStream ts = null;
	    boolean clearDest = false;
		try {
			ts = ikAnalyzer.tokenStream(str, reader);
			CharTermAttribute termAtt = ts.getAttribute(CharTermAttribute.class);
			ts.reset();
			while (ts.incrementToken()){
				token = termAtt.toString();
				if(token.length()>1){
					if(dest==null){
						clearDest = true;
						dest = new HashSet<String>();
					}
					dest.add(token);
				}
			 }
		} catch (IOException e) {
			logger.error(e.getMessage(), e);
		}finally{
			if(clearDest)
				dest.clear();
			if(ts!=null){
				try {
					ts.close();
				} catch (IOException e1) {
					e1.printStackTrace();
				}
			}
		}
	}
	
	private float computeMatchRate(Set<String> keywordsOfMyMoodContent,String target){
		float match = 0f;
		float rate = 1f;
		if(keywordsOfMyMoodContent!=null && !keywordsOfMyMoodContent.isEmpty() && 
				target!=null && !target.trim().isEmpty()){
			StringBuilder sb = new StringBuilder();
			HashSet<String> keyword = new HashSet<String>();
			getKeywords(target, keyword);
			int overlap = 0;
			if(!keyword.isEmpty() && !keywordsOfMyMoodContent.isEmpty()){
				if(keywordsOfMyMoodContent.size()>keyword.size()){
					for(String key : keyword){
						if(keywordsOfMyMoodContent.contains(key)){
							overlap++;
							sb.append(key).append(" ");
						}
					}
				}else{
					for(String key : keywordsOfMyMoodContent){
						if(keyword.contains(key)){
							overlap++;
							sb.append(key).append(" ");
						}
					}
				}
				if(overlap>0){
					match = (float)overlap/keywordsOfMyMoodContent.size();
					match =  (match * 100 / 100) * 100;
				}
			}
		}
		return match;
	}
	
	@RequestMapping(value="/list/with/samemood",method=RequestMethod.GET)
	public @ResponseBody void listWithSameMood(Long pointInTime,Integer gender,String order,int offset,int limit,
			HttpServletRequest request,HttpServletResponse response){
		Status status = new Status(request,response);
		if(order==null) order = "lastLoginAt";
		if(!order.equals("lastLoginAt") && !order.equals("distance")){
			status.setCode(HomiStatusCode.PARAM_ABSENT);
			status.write();
			return;
		}
		if(pointInTime!=null && pointInTime<=0) pointInTime = null;
		if(offset==0 && pointInTime!=null) pointInTime = null;
		
		Integer userId = ServerHelper.getUserId(request);
		UserExtInfo self = this.userExtInfoService.getUserExtInfoByUserId(userId);
		if(self!=null){
			if(gender!=null && gender>2) gender = null;
			if(gender!=null && gender<=0) gender = null;
			
			JSONObject result = new JSONObject();
			JSONArray userArray = new JSONArray();
			Date startTime = null;
			if(pointInTime==null) startTime = new Date();
			else startTime = new Date(pointInTime);
			List<MoodUser> list = moodUserService.listWithSameMood(startTime,self, offset, limit,gender,order);
			MoodUser userOfMatch = null;
			Iterator<MoodUser> iter = list.iterator();
			Mood mood = null;
			JSONObject json = null;
			while(iter.hasNext()){
				userOfMatch = iter.next();
				mood = moodService.getMoodById(userOfMatch.getMoodId());
				userOfMatch.setAvatar(HomiUtil.getRealUrl(userOfMatch.getAvatar()));
				userOfMatch.setMoodContent(mood.getContent());
				userOfMatch.setMoodProtected(true);
				
				//可见度(1所有,2朋友,3私有)
				switch(mood.getVisibility()){
				case 1:
					userOfMatch.setMoodProtected(false);
					break;
				case 2:
					boolean flag = friendService.isFriend(userOfMatch.getId(), userId);
					if(!flag)
						flag = moodService.haveMoodViewPrivilege(userId, mood.getId());
					userOfMatch.setMoodProtected(!flag);
					break;
				case 3:
					boolean haveViewPrivilege = moodService.haveMoodViewPrivilege(userId, mood.getId());
					userOfMatch.setMoodProtected(!haveViewPrivilege);
					break;
				}
				json = JSONObject.fromObject(userOfMatch);
				if(userOfMatch.getLastLoginAt()==null){
					//刚好在该用户登陆时拉取数据
					json.put("lastLoginAt", new Date().getTime());
				}else{
					json.put("lastLoginAt", userOfMatch.getLastLoginAt().getTime());
				}
				userArray.add(json);
				iter.remove();
			}
			iter = null;
			list = null;
			result.accumulate("pointInTime", startTime.getTime());
			result.accumulate("list", userArray);
			status.setResult(result);
		}else{
			status.setCode(HomiStatusCode.USER_NOT_FOUND);
		}
		status.write();
	}
	
	@RequestMapping(value="/list/with/matchmood",method=RequestMethod.GET)
	public @ResponseBody void listWithMatchMood(Integer gender,int offset,int limit,
			HttpServletRequest request,HttpServletResponse response){
		Status status = new Status(request,response);
		JSONObject json = null;
		Integer userId = ServerHelper.getUserId(request);
		UserExtInfo self = userExtInfoService.getUserExtInfoByUserId(userId);
		if(gender!=null && gender>2) gender = null;
		if(gender!=null && gender<=0) gender = null;
		
		if(self!=null){
			List<MoodUser> list = moodUserService.listWithMatchMood(self, offset, limit,gender);
			JSONArray result = new JSONArray();
			MoodUser user = null;
			Iterator<MoodUser> iter = list.iterator();
			while(iter.hasNext()){
				user = iter.next();
				json = JSONObject.fromObject(user);
				json.put("avatar", HomiUtil.getRealUrl(user.getAvatar()));
				result.add(json);
				iter.remove();
			}
			iter = null;
			list = null;
			status.setResult(result);
		}else{
			status.setCode(HomiStatusCode.USER_NOT_FOUND);
		}
		status.write();
	}
	
	@RequestMapping(value="/friend/list",method=RequestMethod.GET)
	public @ResponseBody void listFriend(HttpServletRequest request,HttpServletResponse response){
		Integer userId = ServerHelper.getUserId(request);
		Status status = new Status(request,response);
		List<Friend> list = friendService.listFriend(userId);
		JSONArray result = new JSONArray();
		if(!list.isEmpty()){
			JSONObject json = null;
			User user = null;
			UserExtInfo extInfo = null;
			Friend friend = null;
			Iterator<Friend> iter = list.iterator();
			while(iter.hasNext()){
				friend = iter.next();
				json = new JSONObject();
				user = userService.getUserById(friend.getFriendId());
				extInfo = userExtInfoService.getUserExtInfoByUserId(friend.getFriendId());
				if(user==null) continue;
				json.put("userId", user.getId());
				json.put("gender", user.getGender());
				json.put("nickName", user.getNickName());
				json.put("avatar", HomiUtil.getRealUrl(user.getAvatar()));
				json.put("moodOfLastContact", friend.getMoodForFriendOfLastContact());
				json.put("moodOfCurrent", extInfo.getMood());
				json.put("moodUpdateAt", extInfo.getMoodUpdateAt()==null?0:extInfo.getMoodUpdateAt().getTime());
				json.put("lastContactAt", friend.getLastContactAt()==null?0:friend.getLastContactAt().getTime());
				result.add(json);
				iter.remove();
			}
			iter = null;
			list = null;
		}
		status.setResult(result);
		status.write();
	}
	
	@RequestMapping(value="/friend/delete",method=RequestMethod.GET)
	public @ResponseBody void deleteFriend(int friendId,HttpServletRequest request,HttpServletResponse response){
		Status status = new Status(request,response);
		int rows = friendService.deleteFriend(ServerHelper.getUserId(request), friendId);
		if(rows==0) status.setCode(HomiStatusCode.RELATIONSHIP_ERROR);
		status.write();
	}
	
	@RequestMapping(value="/friend/request/send",method=RequestMethod.GET)
	public @ResponseBody void requestToAddFriend(int targetId,HttpServletRequest request,HttpServletResponse response){
		Status status = new Status(request,response);
		int userId = ServerHelper.getUserId(request);
		if(targetId==userId) status.setCode(HomiStatusCode.API_EXCEPTION);
		else friendService.requestToAddFriend(userId, targetId);
		status.write();
	}
	
	@RequestMapping(value="/friend/request/accept",method=RequestMethod.GET)
	public @ResponseBody void acceptToAddFriend(int targetId,HttpServletRequest request,HttpServletResponse response){
		Status status = new Status(request,response);
		friendService.acceptToAddFriend(ServerHelper.getUserId(request), targetId);
		status.write();
	}
	
	@RequestMapping(value="/friend/request/reject",method=RequestMethod.GET)
	public @ResponseBody void rejectToAddFriend(int targetId,HttpServletRequest request,HttpServletResponse response){
		Status status = new Status(request,response);
		friendService.rejectToAddFriend(ServerHelper.getUserId(request), targetId);
		status.write();
	}
	
	@RequestMapping(value="/changeEmail",method=RequestMethod.POST)
	public @ResponseBody void changeEmail(HttpServletRequest request,HttpServletResponse response) throws Exception {
		String content = IOUtil.getContent4InputStream(request.getInputStream());
		JSONObject json = JSONObject.fromObject(content);
		String email = json.getString("email");
		Status status = new Status(request,response);
		
		if(!Helper.isEmail(email)){
			status.setCode(HomiStatusCode.EMAIL_FORMAT_ERROR);
			status.write();
			logger.info("email format error:" + email);
			return;
		}
		
		User user = userService.getUserByEmail(email);
		if(user != null){
			status.setCode(HomiStatusCode.EMAIL_OCCUPIED);
			status.write();
			logger.info("email already exists. --" + email);
			return;
		}
		
		int userId = ServerHelper.getUserId(request);
		int rows = userService.updateEmailByUserId(email, userId);
		if(rows > 0)
			status.setCode(HomiStatusCode.PROC_SUCCESS);
		else
			status.setCode(HomiStatusCode.API_EXCEPTION);
		status.write();
	}
}
